// 
//  Copyright 2011  Felipe Segade
// 
//    Licensed under the Apache License, Version 2.0 (the "License");
//    you may not use this file except in compliance with the License.
//    You may obtain a copy of the License at
// 
//        http://www.apache.org/licenses/LICENSE-2.0
// 
//    Unless required by applicable law or agreed to in writing, software
//    distributed under the License is distributed on an "AS IS" BASIS,
//    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
//    See the License for the specific language governing permissions and
//    limitations under the License.

namespace FreeType2SharpExample
{
	using System;
	using System.Drawing;
	using System.Drawing.Imaging;
	using System.Runtime.InteropServices;
	using FreeType2Sharp;
	using FreeType2Sharp.Struct;

	class MainClass
	{
		public static void Main (string[] args)
		{
			IntPtr library = new IntPtr ();
			IntPtr pface = new IntPtr ();
			int major, minor, patch;
			
			FreeTypeNative.FT_Init_FreeType (out library);
			
			FreeTypeNative.FT_Library_Version (library, out major, out minor, out patch);
			
			Console.WriteLine ("FreeType version is {0}.{1}.{2}", major, minor, patch);
			
			FreeTypeNative.FT_New_Face (library, args[0], 0, out pface);
			
			FT_Face face = (FT_Face)Marshal.PtrToStructure (pface, typeof(FT_Face));
			
			Console.WriteLine ("{0} has {1} faces", face.family_name, face.num_faces);
			Console.WriteLine ("Index of the selected face is {0}", face.face_index);
			Console.WriteLine ("Selected face has {0} glyphs", face.num_glyphs);
			Console.WriteLine ("The style of this face is {0}", face.style_name);
			Console.WriteLine ("This face has {0} fixed size strikes", face.num_fixed_sizes);
			Console.WriteLine ("This face has {0} charmaps", face.num_charmaps);
			Console.WriteLine ("BBox :");
			Console.WriteLine ("  - xMin : {0}", face.bbox.xMin);
			Console.WriteLine ("  - xMax : {0}", face.bbox.xMax);
			Console.WriteLine ("  - yMin : {0}", face.bbox.yMin);
			Console.WriteLine ("  - yMax : {0}", face.bbox.yMax);
			Console.WriteLine ("Number of units per EM is {0}", face.units_per_EM);
			
			FreeTypeNative.FT_Set_Pixel_Sizes (pface, 0, 16);
			
			FT_Size size = (FT_Size)Marshal.PtrToStructure (face.size, typeof(FT_Size));
			
			Console.WriteLine ("Size metrics :");
			Console.WriteLine ("  - x_ppem : {0}", size.metrics.x_ppem);
			Console.WriteLine ("  - y_ppem : {0}", size.metrics.y_ppem);
			Console.WriteLine ("  - x_scale : {0}", size.metrics.x_scale);
			Console.WriteLine ("  - y_scale : {0}", size.metrics.y_scale);
			Console.WriteLine ("  - ascender : {0}", size.metrics.ascender);
			Console.WriteLine ("  - descender : {0}", size.metrics.descender);
			Console.WriteLine ("  - height : {0}", size.metrics.height);
			Console.WriteLine ("  - max_advance : {0}", size.metrics.max_advance);
			
			uint index = FreeTypeNative.FT_Get_Char_Index (pface, 65);
			
			Console.WriteLine ("Index of character 'A' : {0}", index);
			
			FreeTypeNative.FT_Load_Glyph (pface, index, FT_LOAD.FT_LOAD_DEFAULT);
			
			FreeTypeNative.FT_Render_Glyph (face.glyph, FT_Render_Mode.FT_RENDER_MODE_NORMAL);
			
			FT_GlyphSlot glyph = (FT_GlyphSlot)Marshal.PtrToStructure (face.glyph, typeof(FT_GlyphSlot));
			
			Console.WriteLine ("Bitmap :");
			Console.WriteLine ("  - rows : {0}", glyph.bitmap.rows);
			Console.WriteLine ("  - width : {0}", glyph.bitmap.width);
			Console.WriteLine ("  - pitch : {0}", glyph.bitmap.pitch);
			Console.WriteLine ("  - num_grays : {0}", glyph.bitmap.num_grays);
			Console.WriteLine ("  - pixel_mode : {0}", glyph.bitmap.pixel_mode);
			Console.WriteLine ("  - palette_mode : {0}", glyph.bitmap.palette_mode);
			
			MainClass.CreatePngFromGlyph (glyph);
			
			FreeTypeNative.FT_Done_Face (pface);
			
			FreeTypeNative.FT_Done_FreeType (library);
		}
		
		private static void CreatePngFromGlyph (FT_GlyphSlot glyph)
		{
			Bitmap bitmap = new Bitmap (
				glyph.bitmap.width, 
				glyph.bitmap.rows, 
				glyph.bitmap.pitch, 
				PixelFormat.Format8bppIndexed, 
				glyph.bitmap.buffer);
			
			ColorPalette palette = bitmap.Palette;
			
			// Initialise la palette
			for (int i = 0; i < palette.Entries.Length; i++) {
				palette.Entries[i] = Color.FromArgb (255, i, i, i);
			}
			
			bitmap.Palette = palette;
			
			bitmap.Save ("image.png", ImageFormat.Png);
		}
	}
}
